home *** CD-ROM | disk | FTP | other *** search
- ;************************************************
- ;
- ; Procedure Exec ( Var FileDesc,
- ; ComLine : AnyString;
- ; Var Code : Integer );
- ;
- ;***********************************************
- EXEC proc
- push bp
- mov bp,sp
- push ds
- ;
- Call Get_IP ; copy IP from stack to BX
- jmp start ; IP will point here
- ORGSP dw (0)
- ORGSS dw (0)
- Savoff dw (0)
- parm db 14 dup(0) ; needed by EXEC call
- CMDLin db 127 dup(0) ; DOS command line
- fcb1 db 37 dup(0) ; an FCB
- fcb2 db 37 dup(0) ; another FCB
- Pgm2X db 45 dup(0) ; program to invoke
- Ecode dw (0) ; error code
- ;
- start: add bx,3 ; adjust BX to -> ORGSP
- mov cs:[bx],sp ; save SP in ORGSP
- mov cs:[bx+2],ss ; save SS
- mov word ptr cs:[bx+266],0
- push bx ; save BX
- ;
- ;
- ; *** Shrink
- ; ES has block segment,
- ; BX has block size in paragraphs
- ; AL errors are 7,8,and 9
- ;
- push cs
- pop es
- mov bx,0FFFh
- mov ah,4Ah
- int 21h
- ;
- cmp ax,10
- ja t000
- pop bx
- mov cs:[bx+266],ax
- jmp error
- ;
- t000: call Get_IP
- jmp t001
- SaveA db 100 dup(0)
- t001: add bx,3
- pop di
- mov cs:[di+4],bx ; offset SaveA
- push di
- mov di,bx
- mov ax,cs ; segment of blk
- mov es,ax
- mov cx,0FFFFh
- sub cx,sp
- cmp cx,100
- jna t002
- pop bx
- mov cs:[bx+266],19 ; ecode
- error: jmp leave ; stack too big to save
- t002: mov dx,ss
- mov ds,dx
- mov si,sp
- cld
- rep movsb ; save stack
- ;
- ; *** Create EXEC control block
- ; Format is:
- ; Segment Address of Environ string (2)
- ; Segmented ptr to command line (4)
- ; Segmented ptr to 1st default FCB (4)
- ; Segmented ptr to 2nd default FCB (4)
- ; Total length, 14 bytes.
- ;
- ;
- pop bx
- mov ax,cs:[2Ch] ; PSP envir str
- mov word ptr cs:[bx+6],ax
- lea cx,[bx+20]
- mov cs:[bx+8],cx ; CMDLine offset
- mov cs:[bx+10],cs ; . . and segment
- lea cx,[bx+147] ; FCB1 offset
- mov cs:[bx+12],cx ; . . save it
- mov cs:[bx+14],cs ; . . save segment
- lea cx,[bx+184] ; FCB2 offset
- mov cs:[bx+16],cx ; . . save it
- mov cs:[bx+18],cs ; . . save segment
- ;
- ; ** Move Filedesc from stack
- ; to code segment
- ;
- mov si,[bp+12] ; str offset
- mov ds,[bp+14] ; str segment
- mov cl,[si] ; len of FileDesc
- xor ch,ch
- inc si
- push cs
- pop es
- mov di,bx
- add di,221 ; Pgm2X
- mov dx,di
- cld
- rep movsb ; move Filedesc
- mov byte ptr es:[di],0
- ;
- ; ** Move Command Line from stack
- ; to code segment
- ;
- mov si,[bp+08] ; offset
- mov ds,[bp+10] ; segment
- mov cl,[si] ; length of Com str
- inc si
- mov di,bx
- add di,20 ; ComLin
- rep movsb ; move Command Ln
- mov byte ptr es:[di],0Dh
- ;
- ; *** Load & Execute,
- ; then come back.
- ; AL = 0 for load & execute
- ; AH = 4B for EXEC call
- ; DS:DX points to AsciiZ of filedesc
- ; ES:BX points to parm block
- ;
- mov cx,cs
- mov ds,cx
- mov ss,cx
- mov al,0
- mov ah,4Bh
- mov di,bx
- call Get_IP
- mov cs:[bx+12],di
- mov bx,di
- add bx,6
- int 21h
- ;
- mov bx,0000 ; BX -> ORGSP
- jnc AOK
- mov cs:[bx+266],ax ; Save AX
- AOK: mov dx,bx ; Save BX
- mov bx,0FFFFh ; blks to grow
- mov ah,4Ah ; 'grow' function
- mov cx,cs ; ES will contain . .
- mov es,cx ; the blk segment
- int 21h ; This will fail . .
- mov ah,4Ah ; but BX will have . .
- int 21h ; the maximum size
- mov bx,dx ; restore -> ORGSP
- mov sp,cs:[bx] ; restore SP
- mov di,sp ; setup for move
- mov ax,cs:[bx+2] ; restore SS
- mov ss,ax
- mov es,ax ; ES:DI set
- mov si,cs:[bx+4] ; get offset of . .
- add si,2 ; stack save area
- mov ax,cs
- mov ds,ax ; DS:SI set
- mov cx,0FFFFh ;
- sub cx,sp ; length of stack
- cld
- rep movsb ; restore stack
-
- ;
- Leave:
- pop ds
- mov bp,sp
- mov di,[bp+4] ; Ecode offset
- mov es,[bp+6] ; Ecode segment
- mov ax,cs:[bx+266] ; Ecode setting
- mov es:[di],ax ; set Ecode
- pop bp
- ;
- ret 12
- EXEC endp
- ;
- Get_IP proc
- mov bx,sp
- mov bx,ss:[bx]
- ret
- Get_IP endp